#[allow(dead_code)]
#[derive(Debug,Clone,Copy,PartialEq,Eq)]
#[repr(u8)]
pub enum Color{
    Black = 0,
    Blue = 1,
    Green = 2,
    Cyan = 3,
    Red = 4,
    Magenta = 5,
    Brown = 6,
    LightGray = 7,
    DarkGray = 8,
    LightBlue = 9,
    LightGreen = 10,
    LightCyan = 11,
    LightRed = 12,
    Pink = 13,
    Yellow = 14,
    White = 15,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
struct ColorCode(u8);
//zifuyanse
impl ColorCode {
    fn new(foreground: Color, background: Color) -> ColorCode {
        ColorCode((background as u8) << 4 | (foreground as u8))
    }
}
#[derive(Debug,Clone,Copy,PartialEq,Eq)]
#[repr(C)]
//dangezifu
struct ScreenChar{
    ascill_character:u8,
    color_code:ColorCode,
}

const BUFFER_HEIGHT:usize=25;
const BUFFER_WIDTH:usize=80;

ues volatile::Volatile;

#[repr(transparent)]
struct Buffer{
    chars:[[Volatile<ScreenChar>;BUFFER_WIDTH];BUFFER_HEIGHT],
}

pub struct Writer{
    row:usize,
    column_position: usize,
    color_code: ColorCode,
    buffer: &'static mut Buffer,
}

impl Writer{
    pub fn write_byte(&mut self,byte:u8){
        match byte{
            b'\n'=>self.new_line(),
            byte=>{
                if self.column_position>=BUFFER_WIDTH{
                    self.new_line();
                }
                let row=self.row;
                let col=self.column_position;
                let color_code=self.color_code;
                
                self.buffer.chars[row][col].wrtie(ScreenChar{
                    ascill_character:byte,
                    color_code,
                });
                self.column_position+=1;
            }
        }
    }
    fn new_line(&mut self){
        self.row-=1;
        self.column_position=0;
    }
}
impl Writer{
    pub fn write_string(&mut self,s:&str){
        for byte in s.bytes(){
            match byte{
                0x20..=0x7e=>self.write_byte(byte),
                b'\n'=>self.write_byte(byte),
                _=>self.write_byte(0xfe),
            }
        }
    }
}
//特性可以用于标识哪些类有哪些方法
use core::fmt;
impl fmt::Write for Writer {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.write_string(s);
        Ok(())
    }
}

pub fn print_something(){
    let mut writer=Writer{
        row:BUFFER_HEIGHT-1,
        column_position:0,
        color_code:ColorCode::new(Color::Yellow,Color::Black),
        buffer:unsafe{&mut*(0xb8000 as *mut Buffer)},
    };
    writer.write_byte(b'H');
    writer.write_string("ello ");
    writer.write_byte(b'\n');
    writer.write_string("Wörld!");
}  






